<template>
  <view 
    v-if="inited"
    class="fu-popup"
    :class="{ 'fu-popup--show': show && ready }"
    @touchmove.stop.prevent
    :style="{ 'z-index': zIndex }"
  >
    <!-- 遮罩层 -->
    <view 
      v-if="overlay"
      class="fu-popup__overlay"
      :style="{ 'background-color': overlayColor }"
      :class="{ 'fu-popup__overlay--show': show && ready }"
      @click="handleClickOverlay"
    />
    
    <!-- 内容区域 -->
    <view 
      class="fu-popup__wrapper"
      :class="[
        `fu-popup__wrapper--${position}`,
        { 
          'fu-popup__wrapper--round': round,
          'fu-popup__wrapper--safe': safeAreaInsetBottom && position === 'bottom'
        }
      ]"
      :style="{
        ...contentStyle
      }"
      @click.stop
    >
      <slot />
      <!-- 底部安全区域占位 -->
      <view 
        v-if="safeAreaInsetBottom && position === 'bottom'"
        class="fu-popup__safe-area"
      />
    </view>
  </view>
</template>

<script>
import { disablePageScroll, enablePageScroll } from '../../utils'

/**
 * fu-popup 弹出层组件
 * @description 弹出层容器，用于展示弹窗、信息提示等内容
 * @property {Boolean} show - 是否显示弹出层
 * @property {String} position - 弹出位置，可选值：center/top/bottom/left/right
 * @property {Boolean} overlay - 是否显示遮罩层
 * @property {String} overlayColor - 遮罩层颜色
 * @property {Boolean} closeOnClickOverlay - 是否点击遮罩层后关闭
 * @property {Number} zIndex - 层级
 * @property {Boolean} round - 是否显示圆角
 * @property {Object} contentStyle - 自定义内容样式
 * @property {Boolean} lockScroll - 是否锁定背景滚动
 * @property {Boolean} safeAreaInsetBottom - 是否开启底部安全区适配
 * @event {Function} click-overlay - 点击遮罩层时触发
 */
export default {
  name: 'fu-popup',
  props: {
    show: {
      type: Boolean,
      default: false
    },
    position: {
      type: String,
      default: 'center',
      validator: value => ['center', 'top', 'bottom', 'left', 'right'].includes(value)
    },
    overlay: {
      type: Boolean,
      default: true
    },
    overlayColor: {
      type: String,
      default: 'rgba(0, 0, 0, 0.7)'
    },
    closeOnClickOverlay: {
      type: Boolean,
      default: true
    },
    zIndex: {
      type: Number,
      default: 999
    },
    round: {
      type: Boolean,
      default: false
    },
    contentStyle: {
      type: Object,
      default: () => ({})
    },
    lockScroll: {
      type: Boolean,
      default: true
    },
    safeAreaInsetBottom: {
      type: Boolean,
      default: true
    }
  },
  emits: ['update:show', 'click-overlay'],
  data() {
    return {
      inited: false,
      ready: false
    }
  },
  watch: {
    show: {
      async handler(val) {
        if (val) {
          this.inited = true
          this.ready = false
          if (this.lockScroll) {
            disablePageScroll()
          }
          await this.$nextTick()
		  setTimeout(()=>{
			  this.ready = true
		  },200)
        } else {
          setTimeout(() => {
            if (!this.show) {
              this.ready = false
              if (this.lockScroll) {
                enablePageScroll()
              }
            }
          }, 300)
        }
      },
      immediate: true
    }
  },
  beforeUnmount() {
    if (this.lockScroll && this.show) {
      enablePageScroll()
    }
  },
  methods: {
    handleClickOverlay() {
      this.$emit('click-overlay')
      if (this.closeOnClickOverlay) {
        this.$emit('update:show', false)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.fu-popup {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  will-change: opacity, transform;
  
  &--show {
    pointer-events: auto;
  }
  
  &__overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.7);
    opacity: 0;
    transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    will-change: opacity;
    
    &--show {
      opacity: 1;
    }
  }
  
  &__wrapper {
    position: absolute;
    max-height: 100%;
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    background-color: #fff;
    overflow: auto;
    will-change: transform, opacity;
    
    // 中间弹出
    &--center {
      top: 50%;
      left: 50%;
      transform: translate3d(-50%, -50%, 0) scale(0.8);
      opacity: 0;
      
      .fu-popup--show & {
        transform: translate3d(-50%, -50%, 0) scale(1);
        opacity: 1;
      }
    }
    
    // 顶部弹出
    &--top {
      top: 0;
      left: 0;
      width: 100%;
      transform: translate3d(0, -100%, 0);
      
      .fu-popup--show & {
        transform: translate3d(0, 0, 0);
      }
    }
    
    // 底部弹出
    &--bottom {
      bottom: 0;
      left: 0;
      width: 100%;
      transform: translate3d(0, 100%, 0);
      
      .fu-popup--show & {
        transform: translate3d(0, 0, 0);
      }
      
      &.fu-popup__wrapper--safe {
        padding-bottom: constant(safe-area-inset-bottom); /* iOS 11.0 */
        padding-bottom: env(safe-area-inset-bottom); /* iOS 11.2+ */
      }
    }
    
    // 左侧弹出
    &--left {
      top: 0;
      left: 0;
      width: 80%;
      height: 100%;
      transform: translate3d(-100%, 0, 0);
      
      .fu-popup--show & {
        transform: translate3d(0, 0, 0);
      }
    }
    
    // 右侧弹出
    &--right {
      top: 0;
      right: 0;
      width: 80%;
      height: 100%;
      transform: translate3d(100%, 0, 0);
      
      .fu-popup--show & {
        transform: translate3d(0, 0, 0);
      }
    }
    
    // 圆角样式
    &--round {
      &.fu-popup__wrapper--top {
        border-radius: 0 0 24rpx 24rpx;
      }
      
      &.fu-popup__wrapper--bottom {
        border-radius: 24rpx 24rpx 0 0;
      }
      
      &.fu-popup__wrapper--left {
        border-radius: 0 24rpx 24rpx 0;
      }
      
      &.fu-popup__wrapper--right {
        border-radius: 24rpx 0 0 24rpx;
      }
    }
  }
  
  &__safe-area {
    width: 100%;
    height: constant(safe-area-inset-bottom); /* iOS 11.0 */
    height: env(safe-area-inset-bottom); /* iOS 11.2+ */
    background-color: #fff;
  }
}
</style> 